
#include "NatTravMgr.h"

#include "trav_task.h"

using namespace std;

CNatTravMgr* CNatTravMgr::m_Instance = 0;

CNatTravMgr* CNatTravMgr::GetInstance()
{
	if(!m_Instance)
	{
		m_Instance = new CNatTravMgr;
	}
	return m_Instance;
}

void CNatTravMgr::DelInstance()
{
	if(m_Instance)
	{
		delete m_Instance;
		m_Instance = 0;
	}
}

Int32 CNatTravMgr::GetNatTravInst()
{
	m_Mutex.Lock();
	CTravTask *pTask = new CTravTask;
	Int32 iID = -1;
	if(pTask)
	{
		iID = m_ID++;
		if(m_ID >= 0x7FFFFFFF)
			m_ID = 0;
		m_List[iID] = pTask;
	}
	m_Mutex.Unlock();

	return iID;
}

void CNatTravMgr::FreeNatTravInst(Int32 vID)
{
	m_Mutex.Lock();
	map<Int32, CTravTask*>::iterator it = m_List.find(vID);
	if( it != m_List.end())
	{
		delete it->second;
		m_List.erase(it);
	}
	m_Mutex.Unlock();
}

CTravTask* CNatTravMgr::Find(Int32 vID)
{
	m_Mutex.Lock();
	CTravTask *pTask = NULL;
	map<Int32, CTravTask*>::iterator it = m_List.find(vID);
	if( it != m_List.end())
		pTask = it->second;
	m_Mutex.Unlock();
	
	return pTask;
}


Int32 CNatTravMgr::InitNatTravInst(Int32 vID, Int32 fd, uLong ulStunIP, uLong ulNatServerIP, uShort usNatServerPort,uShort localPort)
{
	CTravTask *pTask = Find(vID);
	if(pTask)
	{
		return pTask->InitTask(fd,ulStunIP,ulNatServerIP,usNatServerPort,localPort);
	}
	return -1;
}

Int32 CNatTravMgr::RegNatTravClient(Int32 vID, uInt64 cID, uShort reqID,uLong& local_nat_ip,uLong& local_lan_ip)
{
	CTravTask *pTask = Find(vID);
	if(pTask)
	{
		return pTask->RegTravClient(cID,reqID,local_nat_ip,local_lan_ip);
	}
	
	return -1;
}

Int32 CNatTravMgr::StartNatTrav(Int32 vID, uInt64 destID, uInt64 reqPeerID, uShort reqID)
{
	CTravTask *pTask = Find(vID);
	if(pTask)
	{
		return pTask->StartNatTrav(destID,reqPeerID,reqID);
	}
#ifdef WIN32
	OutputDebugString("CNatTravMgr-->FindTask Filed!\n");
#endif
	return -1;
}

Int32 CNatTravMgr::HandlePacket(Int32 vID, char* buf, Int32 bufLen, uLong sIP, uShort sPort)
{
	CTravTask *pTask = Find(vID);
	if(pTask)
	{
		return pTask->HandlePacket(buf,bufLen,sIP,sPort);
	}
	return -1;
}

Int32  CNatTravMgr::BeatHeartToNatsvr(Int32 vID, uInt64 localID)
{
	CTravTask *pTask = Find(vID);
	if(pTask)
	{
		return pTask->BeatHeartToNatsvr(localID);
	}
	return -1;
}

Bool CNatTravMgr::GetRemoteNodeAddr(Int32 vID, uLong& rIP, uShort& rPort,uLong &isSameNetwork)
{
	CTravTask *pTask = Find(vID);
	if(pTask)
	{
		return pTask->GetRemoteNodeAddr(rIP,rPort,isSameNetwork);
	}
	return false;
}

CNatTravMgr::CNatTravMgr()
{
	m_ID = 0;
}

CNatTravMgr::~CNatTravMgr()
{
	while(!m_List.empty())
	{
		delete m_List.begin()->second;
		m_List.erase(m_List.begin());
	}
}
